算法设计与分析实验四Word格式.docx
《算法设计与分析实验四Word格式.docx》由会员分享,可在线阅读,更多相关《算法设计与分析实验四Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
{
doubleweight;
//字符出现的概率为实数
intlchild,rchild,parent;
};
建立哈夫曼树的算法如下:
Select函数用来在数组huffTree中选取两个权值最小的根结点,请读者自行完成。
根据已建立的哈夫曼树,规定哈夫曼树的左分支代表0,右分支代表1,则哈夫曼编码即是从根结点到每个叶子结点所经过的路径组成的0和1的序列。
算法如下:
2、背包问题
贪心算法:
procedureKNAPSACK(P,W,M,X,n)
//P(1:
n)和W(1;
n)分别含有按
P(i)/W(i)≥P(i+1)/W(i+1)排序的n件物品的效益值
和重量。
M是背包的容量大小,而x(1:
n)是解向量
realP(1:
n),W(1:
n),X(1:
n),M,cu;
integeri,n;
X←0//将解向量初始化为零
cu←M//cu是背包剩余容量
ifW(i)>
cuthenexitendif
X(i)←1
cu←cu-W(i)
ifi≤nthenX(i)←cu/W(i)
endGREEDY-KNAPSACK
procedureprim(G,)
status←“unseen”//T为空
status[1]←“treenode”//将1放入T
foreachedge(1,w)do
status[w]←“fringe”//找到T的邻接点
dad[w]←1;
//w通过1与T建立联系
dist[w]←weight(1,w)//w到T的距离
whilestatus[t]≠“treenode”do
pickafringeuwithmindist[w]//选取到T最近的节点
status[u]←“treenode”
foreachedge(u,w)do
修改w和T的关系
repeat
3、最小生成树的prim算法
PrimMST(G,T,r){
//求图G的以r为根的MST,结果放在T=(U,TE)中
InitCandidateSet(…);
//初始化:
设置初始的轻边候选集,并置T=({r},¢)
for(k=0;
k<
n-1;
k++){//求T的n-1条树边
(u,v)=SelectLiShtEdge(…);
//选取轻边(u,v);
T←T∪{(u,v)};
//扩充T,即(u,v)涂红加入TE,蓝点v并人红点集U
ModifyCandidateSet(…);
//根据新红点v调整候选轻边集
}
}
4、最短路径问题
最短路径问题是图论研究中的一个经典算法问题,旨在寻找图中两结点之间的最短路径。
给定带权有向图G=(V,E),其中每条边的权是非负实数。
另外,还给定V中的一个顶点,称为源。
现在要计算从源到所有其它各顶点的最短路长度。
这里路的长度是指路上各边权之和。
这个问题通常称为单源最短路径问题。
Dijkstra算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。
主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。
创建两个表,OPEN,CLOSE。
OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
1)访问路网中距离起始点最近且没有被检查过的点,把这个点放入OPEN组中等待检查。
2)从OPEN表中找出距起始点最近的点,找出这个点的所有子节点,把这个点放到CLOSE表中。
3)遍历考察这个点的子节点。
求出这些子节点距起始点的距离值,放子节点到OPEN表中。
4)重复第2和第3步,直到OPEN表为空,或找到目标点。
算法描述:
1)置集合S={2,3,...n},数组d
(1)=0,d(i)=W1->
i(1,i之间存在边)or+无穷大(1.i之间不存在边)
2)在S中,令d(j)=min{d(i),i属于S},令S=S-{j},若S为空集则算法结束,否则转3)
3)对全部i属于S,如果存在边j->
i,那么置d(i)=min{d(i),d(j)+Wj->
i},转2)
Dijkstra算法思想为:
设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径,就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。
在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。
此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
算法具体步骤:
(1)初始时,S只包含源点,即S=,v的距离为0。
U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或)(若u不是v的出边邻接点)。
(2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。
(3)以k为新考虑的中间点,修改U中各顶点的距离;
若从源点v到顶点u(uU)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值的顶点k的距离加上边上的权。
(4)重复步骤
(2)和(3)直到所有顶点都包含在S中。
5、多机调度问题
要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。
约定,每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。
作业不能拆分成更小的子作业。
步骤:
1)把作业按加工所用的时间从大到小排序
2)如果作业数目比机器的数目少或相等,则直接把作业分配下去
3)如果作业数目比机器的数目多,则每台机器上先分配一个作业,如下的作业分配时,是选那个表头上s最小的链表加入新作业。
五、参考程序
2、背包问题贪心算法
#include<
iostream.h>
structgoodinfo
floatp;
//物品效益
floatw;
//物品重量
floatX;
//物品该放的数量
intflag;
//物品编号
//物品信息结构体
voidInsertionsort(goodinfogoods[],intn)
intj,i;
for(j=2;
j<
=n;
j++)
{
goods[0]=goods[j];
i=j-1;
while(goods[0].p>
goods[i].p)
goods[i+1]=goods[i];
i--;
goods[i+1]=goods[0];
}//按物品效益,重量比值做升序排列
voidbag(goodinfogoods[],floatM,intn)
{
floatcu;
inti,j;
for(i=1;
i<
i++)
goods[i].X=0;
cu=M;
//背包剩余容量
n;
if(goods[i].w>
cu)//当该物品重量大与剩余容量跳出
break;
goods[i].X=1;
cu=cu-goods[i].w;
//确定背包新的剩余容量
if(i<
=n)
goods[i].X=cu/goods[i].w;
//该物品所要放的量
for(j=2;
while(goods[0].flag<
goods[i].flag)
cout<
<
"
最优解为:
endl;
cout<
第"
件物品要放:
;
goods[i].X<
}
voidmain()
|--------运用贪心法解背包问题---------|"
|-------------------------------------|"
intj;
intn;
floatM;
goodinfo*goods;
//定义一个指针
while(j)
请输入物品的总数量:
cin>
>
goods=newstructgoodinfo[n+1];
//
请输入背包的最大容量:
M;
inti;
{goods[i].flag=i;
请输入第"
件物品的重量:
goods[i].w;
件物品的效益:
goods[i].p;
goods[i].p=goods[i].p/goods[i].w;
//得出物品的效益,重量比
Insertionsort(goods,n);
bag(goods,M,n);
press<
1>
torunagian"
0>
toexit"
j;
stdio.h>
stdlib.h>
#defineINFINITYINT_MAX
#defineMAX_VERTEX_NUM20
typedefintVRType;
typedefintInfoType;
typedefcharVerTexType;
typedefstructArcCell
VRTypeadj;
InfoType*info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedefstruct
VerTexTypevexs[MAX_VERTEX_NUM];
AdjMatrixarcs;
intvexnum,arcnum;
}MGraph;
VerTexTypeadjvex;
VRTypelowcost;
}closedge[MAX_VERTEX_NUM];
voidCreateGraph(MGraph&
G);
voidMiniSpanTree_PRIM(MGraphG,VerTexTypeu);
intLocateVex(MGraphG,VerTexTypeu);
intminimum(closedgeclose);
voidmain(void)
inti,j;
MGraphG;
CreateGraph(G);
for(i=0;
i<
G.vexnum;
i++)
for(j=0;
j<
j++)
G.arcs[i][j].adj;
"
MiniSpanTree_PRIM(G,'
a'
);
G)
intweigh;
inti,j=0,k=0;
charhand,tide;
inputthenumberforvexnumandarcnum:
G.vexnum>
G.arcnum;
G.arcs[i][j].adj=88;
input"
G.vexnum<
charforvexs:
for(i=0;
G.vexs[i];
G.arcnum<
arc(char,char,weigh):
j=0;
k=0;
G.arcnum;
:
hand;
tide;
weigh;
while(hand!
=G.vexs[j])
j++;
while(tide!
=G.vexs[k])
k++;
G.arcs[j][k].adj=weigh;
G.arcs[k][j].adj=weigh;
voidMiniSpanTree_PRIM(MGraphG,VerTexTypeu)
inti,j,k=0;
closedgeclose;
k=LocateVex(G,u);
for(j=0;
j++)
if(j!
=k)
close[j].adjvex=G.vexs[k];
close[j].lowcost=G.arcs[k][j].adj;
close[j].lowcost=88;
close[j].adjvex='
\0'
close[k].lowcost=0;
close[k].adjvex=u;
for(i=1;
{
k=minimum(close);
close[k].adjvex;
---->
G.vexs[k]<
close[k].lowcost<
for(j=0;
j<
G.vexnum;
if(G.arcs[k][j].adj<
close[j].lowcost)
intLocateVex(MGraphG,VerTexTypeu)
intk=0;
while(G.vexs[k++]==u)
returnk-1;
return0;
intminimum(closedgeclose)
intj1=0,client=88,j2;
while(close[j1].adjvex!
='
)
if(client>
close[j1].lowcost&
&
close[j1].lowcost!
=0)
client=close[j1].lowcost;
j2=j1;
j1++;
returnj2;
4、最短路径问题
#include<
fstream>
#include<
cstring>
usingnamespacestd;
constintMaxNum=1000000;
//边权最大值
intn;
//节点数目
intdist[501];
//到节点1的最短路径值
boolstate[501];
//节点被搜索过状态指示
intdata[501][501];
//邻接矩阵
//查找权值最小的节点
intfindmin()
{
intminnode=0,min=MaxNum;
for(inti=1;
i<
i++)
if((dist[i]<
min)&
(!
state[i]))
min=dist[i];
minnode=i;
}
returnminnode;
intmain()
ifstreamin("
dijkstra.in"
ofstreamout("
dijkstra.out"
memset(state,0,sizeof(state));
in>
n;
for(intp=1;
p<
p++)
for(intq=1;
q<
q++)
data[p][q];
if(data[p][q]==0)data[p][q]=MaxNum;
//初始化
dist[i]=data[1][i];
state[1]=true;
intdone=1;
while(done<
n)
intnode=findmin();
if(node!
=0)
done++;
//找到的点的数目加1
state[node]=true;
//标记已经找到了从节点1到节点node的最短路径
i++)//更新还没有找到的点的路径值
if((dist[i]>
dist[node]+data[node][i])&
dist[i]=dist[node]+data[node][i];
elsebreak;
for(intk=1;
k<
k++)
if(dist[k]==MaxNum)
out<
-1;
else
dist[k];
if(k==n)
in.close();
out.close();
return0;
}
5、多机调度问题
typedefstructJob
intID;
//作业号
inttime;
//作业所花费的时间
}Job;
typedefstructJobNode//作业链表的节点
JobNode*next;
}JobNode,*pJobNode;
typedefstructHeader
//链表的表头
ints;
pJobNodenext;
}Header,pHeader;
intSelectMin(Header*M,intm)
intk=0;
for(inti=1;
m;
if(M[i].s<
m[k].s)k=i;
returnk;