完整word版图论算法及matlab程序的三个案例docxWord格式.docx
- 文档编号:21104283
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:20
- 大小:23.97KB
完整word版图论算法及matlab程序的三个案例docxWord格式.docx
《完整word版图论算法及matlab程序的三个案例docxWord格式.docx》由会员分享,可在线阅读,更多相关《完整word版图论算法及matlab程序的三个案例docxWord格式.docx(20页珍藏版)》请在冰豆网上搜索。
%标记集合S和S的补
r=zeros(3,n);
r(1,:
)=1:
n;
r(2,2:
end)=realmax;
%初始化
fori=2:
%控制循环次数
mm=realmax;
forj=find(s==0);
%集合S中的顶点
fork=find(s==1);
%集合S补中的顶点
if(r(2,j)+ma(j,k)<
r(2,k))
r(2,k)=r(2,j)+ma(j,k);
r(3,k)=j;
end
if(mm>
mm=r(2,k);
t=k;
s(1,t)=0;
%找到最小的顶点加入集合S
re=r;
1.2动态规划求解最短路径
动态规划是美国数学家RichardBellman在1951年提出来的分析一类多阶段决策过程的最优化方法,在工程技术、工业生产、经济管理、军事及现代化控制工程等方面均有着广泛的应用。
动态规划应用了最佳原理:
假设为了解决某一
优化问题,需要依次作出n个决策D1,D2,L,Dn,如若这个决策是最优的,对于
任何一个整数k,1<
k<
n,不论前面k个决策是怎样的,以后的最优决策只取决
于由前面决策所确定的当前状态,即Dk1,Dk2,L,Dn也是最优的。
如图1,从A1点要铺设一条管道到A16点,中间必须要经过5个中间站,第
一站可以在{A2,A3}中任选一个,第二、三、四、五站可供选择的地点分别是:
{A4,A5,A6,A7},{A8,A9,A10},{A11,A12,A13},{A14,A15}。
连接两地管道的距离用连线上的数字表示,要求选一条从A1到A16的铺管线路,使总距离最短。
1
A4
6
2
3
8
A
11
14
5
4
A9
A12
A16
7
15
A10
A13
A7
图1可选择的管道图
解决此问题可以用穷举法,从A1到A16有48条路径,只须比较47次,就可
得到最短路径为:
A1→A2→A5→A8→A12→A15→A16,最短距离为18。
也可以使用Dijkstra算法。
这里,我们动态规划解决此问题。
注意到最短
路径有这样一个特性,即如果最短路径的第
k站通过
k,则这一最短路径在由
P
Pk出发到达终点的那一部分路径,对于始点为
Pk到终点的所有可能的路径来说,
必定也是距离最短的。
根据最短路径这一特性,启发我们计算时从最后一段开始,从后向前逐步递推的方法,求出各点到A16的最短路径。
在算法中,我们用数组六元数组ss表示中间车站的个数(A1也作为中间车
站),用距离矩阵path表示该图。
为简便起见,把该图看作有向图,各边的方向均为从左到右,则path不是对称矩阵,如path(12,14)=5,而path(14,12)=0(用
0表示不通道路)。
用3′16矩阵spath表示算法结果,第一行表示结点序号,第
二行表示该结点到终点的最短距离,第三行表示该结点到终点的最短路径上的下
一结点序号。
下面给出MATLAB实现算法。
function[scheme]=ShortestPath(path,ss)
%利用动态规划求最短路径
%path是距离矩阵,ss是车站个数
n=size(path,1);
%结点个数
scheme=zeros(3,n);
%构造结果矩阵
scheme(1,:
%设置结点序号
scheme(2,1:
n-1)=realmax;
%预设距离值
k=n-1;
%记录第一阶段结点最大序号
fori=size(ss,2):
-1:
1;
%控制循环阶段数
forj=k:
(k-ss(i)+1);
%当前阶段结点循环
fort=find(path(j,:
)>
0);
%当前结点邻接结点
ifpath(j,t)+scheme(2,t)<
scheme(2,j)
scheme(2,j)=path(j,t)+scheme(2,t);
scheme(3,j)=t;
k=k-ss(i);
移入下一阶段
先在MATLAB命令窗口中构造距离矩阵path,再输入:
>
ShortestPath(path,ss)
得到以下结果:
9
10
12
13
16
18
将该结果表示为图,即为图1粗线所示。
棋盘覆盖问题
1.1问题的提出
在一个2k2k个方格组成的棋盘中,若恰有一个方格与其他方格不同,则称
该方格为一特殊方格,且称该棋盘为一特殊的棋盘。
如图1就是当k3时的特
殊棋盘。
棋盘覆盖问题中,我们要用图2所示4种不同形态的L形骨牌覆盖一个
特殊棋盘,且任何2个L型不得重叠覆盖。
图1当k=3时的特殊棋盘
(a)(b)(c)(d)
图24种不同形态的L型骨牌
1.2问题的分析
易知,用到的L型骨牌个数恰为(4k1)/3。
利用分治策略,我们可以设计出解棋盘覆盖问题的一个简捷的算法。
当k>
0时,我们将2k2k棋盘分割为4个2k12k1子棋盘如图3两粗实线所
示。
图3棋盘分割
图4关键结点
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。
为了将这3个无特殊方格的子棋盘转化为特殊棋盘,我们可以用一个L型骨牌覆盖
这3个较小棋盘的会合处,如图4中央L型骨牌所示,这3个子棋盘上被L型骨牌覆盖的方格就成为该棋盘上的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。
递归地使用这种分割,直至棋盘简化为11棋盘。
1.3算法的MATLAB实现
首先特殊方格在棋盘中的位置可以用一个12的数组sp表示;
对于图2所示的4种L型骨牌,可用数字1,2,3,4表示;
对于特殊棋盘的骨牌覆盖表示,只
须注意到图4所示的关键点,对每个关键点,给定一种L型骨牌,就能覆盖整个
棋盘,所以对于2k2k的特殊棋盘的骨牌覆盖,可用一个
(2k
1)(2k1)的矩阵
表示。
按照这种思想,图4的矩阵表示为:
k,特殊方格位置为:
[1,4]
,覆盖矩阵为:
=4
下面是在MATLAB中的棋盘覆盖实现程序。
functionre=chesscover(k,sp)
%解决棋盘的覆盖问题
%棋盘为2^k*2^k,sp为特殊方格的棋盘位置
globalcovermatrix
covermatrix=zeros(2^k-1,2^k-1);
even1=floor(sp(1,1)/2)*2==sp(1,1);
%判断水平位置是否是偶数
even2=floor(sp(1,2)/2)*2==sp(1,2);
%判断竖直位置是否是偶数
ifeven1==1&
&
even2==0%找出找出特殊方格相对关键结点的位置
i=4;
else
i=even1+even2+1;
tempfun(1,1,k,[sp(1,1)-even1,sp(1,2)-even2,i]);
re=covermatrix;
functiontempfun(top,left,k,tp)%子函数,tp为转换后特殊方格在棋盘网
络的相对位置
ifk==1
switchtp(1,3)
case1
covermatrix(tp(1,1),tp(1,2))=3;
case2
covermatrix(tp(1,1),tp(1,2))=4;
case3
covermatrix(tp(1,1),tp(1,2))=1;
case4
covermatrix(tp(1,1),tp(1,2))=2;
half=2^(k-1);
i=top+half-1;
j=left+half-1;
iftp(1,1)<
i
iftp(1,2)<
j%特殊方格在左上
covermatrix(i,j)=3;
%添加类型为3的L型骨牌
tempfun(top,left,k-1,tp);
tempfun(top,left+half,k-1,[i-1,j+1,4]);
tempfun(top+half,left+half,k-1,[i+1,j+1,1]
);
tempfun(top+half,left,k-1,[i+1,j-1,2]);
else%特殊方格在右上
covermatrix(i,j)=4;
%添加类型为4的L型骨牌
tempfun(top,left,k-1,[i-1,j-1,3]);
tempfun(top,left+half,k-1,tp);
iftp(1,2)>
j%特殊方格在右下
covermatrix(i,j)=1;
%添加类型为3的L型骨牌
tempfun(top+half,left+half,k-1,tp);
else%特殊方格在左下
covermatrix(i,j)=2;
tempfun(top+half,left,k-1,tp);
在MATLAB命令窗口中输入指令chesscover(3,[1,4])
将会得到如上面矩阵一样的结果。
结合VC++,利用MATLAB引擎库函数,可以给出了棋盘覆盖的图形
最优树的应用实例
已知某通信系统在通信联络中只可能出现8种字符,其概率分别为0.05,
0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计一种编码,使得信息包长
度达到最小。
ASCII码是用8位(一个字节)表示一个字符,这种表示方法方便,易于理解,是计算机系统中常用的字符表示方法。
在信息传输领域,可能有些字符出现的频率非常高,而有些字符出现的频率很低,若依然用此方法表示数据,则显得过于庞大,如果用不定长编码表示字符,频率出现高的字符用较短的编码表示,频率出现低的字符用较长的编码表示,则可以使得数据量大大减少。
比如AAAABBBAAABBBBCCCCCCBBB,用ASCII码表示占用184位,若用00表示C,01表示A,1表示B,则该字串占用位数为36,压缩率达到19.6%,这种编码称为哈夫曼编码。
当然也可用其它方式压缩数据,例如上面字符串写成
4A3B3A4B6C3B,而达到压缩数据的目的。
1.3哈夫曼树的构造
要构造哈夫曼编码,需要构造哈夫曼树(即最优树)。
哈夫曼最早给出了一
个带有一般规律的算法,俗称哈夫曼算法。
现叙述如下:
①根据给定的n个概率(或频率)构造一个集合F{f1,f2,L,fn},同时这
n个值对应树T的n个结点,置in1。
②在集合F中选择两个最小的值求和作为fi加入集合F中;
在树T中构造一结点,使得该结点是两最小值对应结点的父结点。
③在集合F中删除两最小值,并置ii1。
④重复②和③,直到i2n1或集合F只有一个元素为止。
这样形成的一棵树就是哈夫曼树(最优树)。
上面所提到的字符串和题目给出的概率所形成的哈夫曼树分别如图1和图2(为方便起见,每个概率值乘上了100)。
100
23
42
58
19
29
B
C
图1
图2
1.4用MATLAB哈夫曼算法
在MATLAB中哈夫曼算法,可用一个5(2n1)的矩来表示哈夫曼,矩的含如表6-3-3所示。
表1哈夫曼算法数据构
字符
⋯⋯⋯2n-1
序号
概率
父点
左右子
0表示
表示
志
左子
右子
是否在
1在集
不在
集合F
合F
下面出哈夫曼的生成算法:
functionhtree=HuffmanTree(pro)
%构造哈夫曼
%pro一概率向量
n=size(pro,2);
%得到字符个数
tree=ones(6,2*n-1);
%构造数据构
tree(1,:
(2*n-1);
%填充点序号
tree(5,(n+1):
end)=0;
%置点是否在集合
tree(2,1:
n)=pro;
%设置概率
tree(6,1:
%记录查找的结点对顺序
fori=(n+1):
%循环控制
[l,r]=findminval(tree);
%找到集合中两个最小的值的序号
tree(2,i)=tree(2,l)+tree(2,r);
%得到父结点概率值
tree(5,i)=1;
%设置新构造结点在集合中
tree(3,l)=i;
tree(3,r)=i;
%设置父结点序号
tree(4,l)=0;
tree(4,r)=1;
%设置左右标志
tree(5,l)=0;
tree(5,r)=0;
%设置不在集合中
tree(6,l)=i-n;
tree(6,r)=i-n;
%记录该次删除的结点对顺序
htree=tree;
function[l,r]=findminval(tree)
s=find(tree(5,:
)==1);
ifsize(s,2)<
error('
Errorinput!
'
firval=realmax;
secval=realmax;
fori=s;
iffirval>
tree(2,i)
ifsecval>
firval
second=first;
secval=firval;
first=i;
firval=tree(2,i);
elseifsecval>
second=i;
secval=tree(2,i);
l=min([first,second]);
r=max([first,second]);
该算法还显示了删除结点对的先后顺序。
在MATLAB命令窗口输入以下指令:
a=[529781423311];
HuffmanTree(a)
将会显示如表6-3-4所示结果。
表2哈夫曼树
把该表画成一张图,就是图2。
若约定左子树表示0,右子树表示1,从根结点走到叶子结点,则可得到各叶子结点的哈夫曼编码(见图2)。
本例各字符的哈夫曼编码分别为:
字符1(概率值0.05)
:
0110
字符2(概率值0.29)
10
字符3(概率值0.07)
1110
字符4(概率值0.08)
1111
字符5(概率值0.14)
110
字符6(概率值0.23
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word 版图 算法 matlab 程序 三个 案例 docx