实验三、最佳路径选取问题

  • 格式:doc
  • 大小:158.00 KB
  • 文档页数:23

下载文档原格式

  / 23
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验三:管道铺设施工的最佳方案问题

一、问题描述

1、实验题目:

需要在某个城市n 个居民区之间铺设煤气管道,则在这n 个居民小区之间只需要铺设n-1条管道即可。假设任意两个校区之间都可以铺设管道,但由于地理环境不同,所需要的费用也不尽相同。选择最优的方案能使总投资尽可能小,这个问题即为求无向网的最小生成树。 2、基本要求:

在可能假设的m 条管道中,选取n-1条管道,使得既能连同n 个小区,又能使总投资最小。每条管道的费用以网中该边的权值形式给出,网的存储采用邻接表的结构。 3、测试数据:

使用下图给出的无向网数据作为程序的输入,求出最佳铺设方案。

图为小区煤气管道铺设网及其参考解

数据输入与输出:从键盘或文件读入上图中的无向网,以顶点对(i ,j )的形式输出最小生成树的边。 二、需求分析

1、本程序通过用户提供的信息,可给出n 个小区之间的管道铺设的最佳路径。

98.7

44.6

41.1 10.5

12.1

A

I D

B

C

E

G

F

H

32.8

85.6

67.3

21.3 5.9

18.28.7

52.5 56.4 79.2

5.9

32.8

12.1

8.7

79.2

B

I H

F

E

D

C A

41.1 21.3 10.5

G

2、当用户输入必要的信息完毕后,提示用户输入小区的起点。

3、程序将自动给出以某个小区作为起点的最佳路径。 三、概要设计 1、设计思路

这是一个运筹学中的规划问题,求解最佳方案。先选一个点作为起点,从这个点选取费用最小的一条路径。算法的基本思想是:对于图G=(V,E),V 是包含n 个顶点的顶点集,E 是包含m 条弧的弧集,(v,w )是E 中从v 到w 的弧,c(v,w)是弧(v,w )的非负权值,设s 为V 中的顶点,t 为V 中可由s 到达的顶点,则求解从s 至t 的具有最小弧权值和的最短路径搜索过程如下: ①将v 中的顶点分为3类:已标记点、未标记点、已扫描点。将s 初始化为已标记点,其他顶点为未标记点。为每个顶点v 都建立一个权值d 和后向顶点指针p,并将d 初始化如下:d(v)=0,v=s;d(v)= ∞,v ≠s 。

②重复进行扫描操作:从所有已标记点中选择一个具有最小权值的顶点v,并将其设为已扫描点,然后检测每个以v 为顶点的弧(v,w ),若满足d(v)+c(v)

对于无向网络,采用邻接表的结构存储。 ①抽象数据类型

ADT R[N]{

数据对象:D={ i a |i a ∈int, i=1,2,3.... } 数据关系:R=φ }}ADT R[N]

定义一个数组a[],存储任意两点之间的权值。

定义一个数组b[],每个数组元素表示当前所找到的从始点vi 到vk 最小费用的值。它的初态为:若从vi 到vj 有边,则为边的权值;否则置为∞。 定义一个数组fee[],其元素fee[k]用以记录vi 到vk 最短路径中vk 的直接

前驱结点的序号,如果vi到vk存在边,则fee[k]初值为i。

定义一个数组tag[],记录某个顶点是否已计算过最小费用,如果tag[k]=0,则vk∈V-S,否则vk∈S。初始值除tag[i]=1外,所有值均为0。

②边表结点结构体

EdgeNode//边表结点

{

定义一个访问标记bool flag;

顶点域char name;

顶点所能达到的结点char s_name;

边上信息double fee;

结点的指针域EdgeNode *next;

};

③顶点表结构体

Vnode//顶点表结点

{

顶点域char vname;

边表的头指针EdgeNode *firstedge;

};

④无向网图的结构体

Algraph

{

邻接表类型的数组Vnode AdjList[MaxV erNum];

邻接表的顶点数与边数int n,e;

};

⑤自定义函数

void Create_Algraph(Algraph *G)//创建无向网图

{

根据边及顶点的个数

for()

{ 申请空间,并将相应的信息填入空间中}

}

void Print_Algraph(Algraph *G);//以邻接表的存储形式打印出网络的信息void Change_Flag(Algraph *G,char name)

{ 若结点被访问,就将flag修改为1;}

EdgeNode *Min_Fee(Algraph *G,char name)//求去最小费用的函数

{

对于一个顶点,若与其相连的顶点的费用,都被访问过(即flag=1)

那么就返回该结点的上一级结点

如果至少有一条路径没被访问,那么就将最小费用的结点返回;

}

void Min_Tree(Algraph *G,Vnode *V,char name)/*求解最小生成树,name为

最小生成树的根节点*/ {

根据给出的根结点,并调用Min_Fee()函数,求取最小费用,在与其他结点的最小费用相比,在求出最小费用;

将最小费用的结点用链表的形式存储;

}

void Print_MinTree(EdgeNode *N); //打印最小生成树

double Total_Fee(Vnode *V);//计算最小生成树对应的费用

⑥本程序的保护模块: