算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx

上传人:b****6 文档编号:5244780 上传时间:2022-12-14 格式:DOCX 页数:15 大小:94.51KB
下载 相关 举报
算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx_第1页
第1页 / 共15页
算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx_第2页
第2页 / 共15页
算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx_第3页
第3页 / 共15页
算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx_第4页
第4页 / 共15页
算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx

《算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx》由会员分享,可在线阅读,更多相关《算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx(15页珍藏版)》请在冰豆网上搜索。

算法设计 实验 报告 K路归并 2路归并 单源点最短路径.docx

算法设计实验报告K路归并2路归并单源点最短路径

《算法设计》实验报告

 

姓名:

xxx

学号:

U20091519x

班级:

0911

专业:

计算机科学与技术

 

报告日期:

2011/11/10

 

实验一(k路归并)

问题描述及分析:

给定k值和n个文件内的记录(即长度)q1,q2,q3,..qn,每次归并k个文件,找出最优归并模式。

由于归并一个具有x个记录的文件和一个具有y个文件时间复杂度为O(x+y),因此对于度量标准的一种明显选择是:

每一步归并权值最小的k个文件。

算法思想:

由最优二路归并树的思想,可以导出K路归并的贪心算法,即在每一步归并时,都选择k棵具有最小长度的子树(权值分别为q1,q2,q3,..qk)用于归并,用权值为q1+q2+q3+..+qk的新结点取代前K个结点,再与其它结点一起按此方法继续归并。

在此情况下,相应的归并树是一棵K元树。

由于所有的内部结点的度必须为K,因此对于n的某些值,就不与K元归并树相对应。

所以,有必要引入一定量的虚外部结点,且为不影响所产生k元树的带权外部路径长度,因此需将每个虚结点的权值赋0。

这样,最后得到的归并树一定是满k元树。

程序设计:

分两种情况,若k=2即二路归并时,不需要引入“虚”外部结点,每次只需将权值最小的结点两两归并。

若k≠2,根据满k元树的性质可知,仅当nmod(k-1)=1时,不需要引入“虚”外部结点;当nmod(k-1)=0时,需引入1个“虚”外部结点;其他情况需引入”虚”外部结点个数为k-(nmod(k-1))。

添加虚外部结点后,外部结点与内结点数的有如下关系关系:

inner_node=(outer_node-1)/(k-1)。

在本程序中,各文件的长度即权值,而且由于每次归并前,结点已经按权值递增的次序排列,所以每次归并仅需要将前K个元素归并即可。

源代码(见源代码merge.c):

#include

/*按照文件长度由小到大排序并显示*/

voidsort_show(intstart,intend,intk,int*s)

{/*start、end分别为数组首末元素的小标*/

inti,j,cur,temp;

for(i=start;i

{

cur=i;

for(j=i+1;j<=end;j++)

{

if(s[j]

}

if(cur!

=i)

{

temp=s[cur];

s[cur]=s[i];

s[i]=temp;

}

}

if(0!

=(end-start))

{

for(i=start;i<=end;i++)

{/*将前k个元素用括号括起来*/

if(i==start)printf("(%d\t",s[i]);

elseif(i==start+k-1)printf("%d)\t",s[i]);

elseprintf("%d\t",s[i]);

}

}

elseprintf("%d",s[start]);

}

 

main()

{/*文件个数file_num,k路归并,内部结点数即归并次数inner_node,需要引入的“虚”外部结点数unreal_node,总的外部结点数(包括虚结点)outer_node*/

intfile_num,k,x,inner_node,outer_node,unreal_node;

inti,j,count,sum,*list;

printf("inputthenumberoffiles:

");

scanf("%d",&file_num);

printf("inputk:

");

scanf("%d",&k);

/*若k=2即二路归并时,不需要引入“虚”外部结点*/

if(2==k)unreal_node=0;

else

{/*若k!

=2时,仅当file_nummod(k-1)=1时,不需要引入“虚”外部

结点*/

x=file_num%(k-1);

if(0==x)unreal_node=1;

elseif(1==x)unreal_node=0;

elseunreal_node=k-x;

}

outer_node=unreal_node+file_num;

inner_node=(outer_node-1)/(k-1);

/*申请该数组用于存放各文件(包括引入的虚结点)的长度*/

list=(int*)malloc(outer_node*sizeof(int));

for(i=0;i

printf("\ninputlengthofeachfile:

\n");

for(i=unreal_node;i

{

printf("Len[%d]=",i-unreal_node+1);

scanf("%d",&list[i]);

}

for(i=0,count=0;i<=outer_node-1;i=i+k-1)

{

printf("\n\nafter%dmerge:

\n",count);

sort_show(i,outer_node-1,k,list);/*将每次归并后的结果输出*/

sum=0;

if(outer_node-1!

=i)

{

for(j=count*(k-1);j<=(count+1)*(k-1);j++)

sum+=list[j];/*sum用于求取每次归并的结果*/

}

list[j-1]=sum;

count++;/*count计数归并的次数*/

}

getch();

}

 

测试实例:

给定8个文件,长度依次为3、2、5、1、6、9、12、8,请分别用2路归并和3路归并。

、分析:

归并树如下图所示(外部结点用方框表示,内结点用圆表示):

2路归并树3路归并树

46

46

11

26

20

23

12

14

11

12

9

3

3

5

6

8

9

6

8

6

5

3

3

0

1

2

2

1

、运行结果(输入k值、文件个数及个文件长度,输出每次归并后的结果):

1K=2即二路归并时,输入8个文件,长度依次为3、2、5、1、6、9、12、8。

2k≠2比如k=3时,输入8个文件,长度依次为3、2、5、1、6、9、12、8。

其中,每次输出结果中括号内的部分为下次需要归并的元素,最前面的0表示引入的“虚”外部结点。

 

实验二(单源点最短路径)

问题描述与分析:

已知一个n结点的有向图G=(V,E)和各边的权w(e),求由G中的某指定点v到其它个结点的最短路径。

为制定产生最短路径的贪心算法,对于这个问题应该想出一个多级解决办法和一种最优的量度标准。

算法思想:

设S表示对其已经生成了最短路径的那些结点(包含起点v)的集合。

对于不在S中的w,设dist[w]是从v开始只经过S中的结点而在w结束的那条最短路径的长度,则有以下结论:

①如果下一条最短路径是到结点u,则这条路径是从v开始而在u处终止,并且只通过了那些在S中的结点。

②所生成的下一条路径的终点必定是所有不在S内的结点中具有最小距离dist[u]的结点。

③在像②中那些选出了结点u并生成从v到u的最短路径后,结点就成为S中的一个成员。

此时,若dist[w]减小,那是由于有一条从v经u到w的更短路径,其中从v到u的路就是这样一条最短的路,而从岛的路径是边,且这条路径的长度是dist[]+w(u,w)。

程序设计:

假定G中的n个结点被标上0到n-1,若结点i在数组S中,则是[i]=1,若不在s中,则s[i]=0。

已给定该图的成本邻接矩阵,cost[i][j]是边的权,则在边不在E(G)中的情况下,cost[i][j]被置以某个无穷大的数+∞。

对于i=j时,cost[i][j]被置以0。

每次判断时,若dist[u]+cost[u][w]添加到w的路径path中。

当n个结点中有n-1个结点在S中时,即需要判断n-2次,算法才会终止。

源代码(见源代码path.c):

#include

#defineN7

#defineINFINITY32767/*定义无穷大‘+∞’*/

main()

{/*若结点i在S中,则s[i]=1,否则s[i]=0;dist[j]表示结点v到j最短路径长度,

并用path[][]保存路径*/

inti,j,k,n=N,v,u,w;

ints[N],dist[N],path[N][N];

intcost[N][N]={/*初始化成本邻接矩阵*/

{0,20,50,30,INFINITY,INFINITY,INFINITY},

{INFINITY,0,25,INFINITY,INFINITY,70,INFINITY},

{INFINITY,INFINITY,0,40,25,50,INFINITY},

{INFINITY,INFINITY,INFINITY,0,55,INFINITY,INFINITY},

{INFINITY,INFINITY,INFINITY,INFINITY,0,10,70},

{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,0,50},

{INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,0}};

for(i=0;i

{/*输出成本邻接矩阵,其中‘+’表示+∞*/

for(j=0;j

{

if(INFINITY==cost[i][j])printf("%s","+\t");

elseprintf("%d\t",cost[i][j]);

}

printf("\n");

}

loop:

printf("\ninputstart_point:

");/*输入起点下标v*/

scanf("%d",&v);

if(v>=n||v<0)/*若输入越界,提示再次输入*/

{

printf("inputover_border!

!

\n");

gotoloop;

}

for(i=0;i

{/*对数组s、dist和path进行初始化*/

s[i]=0;

dist[i]=cost[v][i];

if(INFINITY!

=dist[i])

{

path[i][0]=v;

path[i][1]=i;

path[i][2]=-1;

}

}

s[v]=1;/*首先将v计入S*/

dist[v]=0;

for(i=1;i

{/*在S之外求取结点u,使得dist[u]最小*/

for(j=0;j

if(0==s[j])

{

u=j;

break;

}

for(k=j+1;k

if(0==s[k]&&dist[k]

{

u=k;

break;

}

s[u]=1;/*将结点u计入S*/

for(w=0;w

{

if(0==s[w]&&(dist[u]+cost[u][w])

{/*判断,修改距离dist[],并用path[][]记录路径*/

dist[w]=dist[u]+cost[u][w];

for(i=0;-1!

=path[u][i];i++)path[w][i]=path[u][i];

path[w][i]=w;

path[w][i+1]=-1;

}

}

}

printf("\n");

for(i=0;i

if(i!

=v)

{/*输出v到其它各节点的最短路径,若不可达,输出Notreachable*/

if(INFINITY==dist[i])printf("v[%d]-->v[%d]:

Notreachable!

",v,i);

else

{

printf("v[%d]-->v[%d]:

distance=%d",v,i,dist[i]);

printf("\tpath=");

for(j=0;-1!

=path[i][j];j++)

{

printf("v%d",path[i][j]);

if(-1!

=path[i][j+1])printf("->");

}

}

printf("\n");

}

getch();

}

测试实例:

求下图中V0到其余各个结点的最短路径。

V5

20

V0

V2

50

50

50

70

25

V1

V6

25

40

10

70

V3

30

55

V4

、分析:

最短路径算法执行追踪

迭代

选取的结点

S

dist[]

0

1

2

3

4

5

6

置初值

1

0

20

50

30

+∞

+∞

+∞

1

2

1,2

0

20

45

30

+∞

90

+∞

2

4

1,2,4

0

20

45

30

85

90

+∞

3

3

1,2,4,3

0

20

45

30

70

90

+∞

4

5

1,2,4,3,5

0

20

45

30

70

80

140

5

6

1,2,4,3,5,6

0

20

45

30

70

80

130

、运行结果(比如先输入8,会提示越界,再输入0,则正常显示):

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1