一、 实验目的
1.目的:掌握图的存储、构建、搜索等操作和应用,能用最短路径及其搜索等算法编制较综合性的程序,求解最优路线问题,进行程序设计、数据结构和算法设计等方面的综合训练。
2.任务:设计一个城市交通咨询模拟系统,利用该系统实现至少两种最优决策:最短路程到达、最省时到达等线路规划。
二、 实验内容及要求
1、 任务描述
实验内容:
用户驾车出行由于出行目的的不同对道路路线选择的要求也有不同。例如,有的希望在途中的路程尽可能短,有的则可能希望路程中时间最短。为了能满足广大旅客的需求,编制一个城市交通咨询模拟系统,选取城市部分位置、道路抽象为程序所需要图的顶点和边,并以城市道路长度(路程),道路的某时段的速度等信息作为图结点中的弧信息,为旅客提供这两种最优决策的交通咨询。
输入和输出:
输入形式:
构建图时,输入顶点、弧涉及的信息,包括:起始地、目的地、长度、该弧此时间段的平均速度等信息;
用户或者客户要输入出发地和目的地,并选择何种最优决策的路线规划。
输出形式:根据用户需求输出对应信息
输出最短路程所需要的路线信息和最短路程;
输出最短时间所需要的路线信息和最短时间。
实验要求:
实现一个简单的交互式界面,包括系统菜单、清晰的输入提示等。
根据输入的交通图数据,以图形化形式把交通图显示在屏幕上。
以图形化形式把最优路线显示在屏幕上。
能够上机编辑、调试出完整的程序。
2、 主要数据类型与变量
const int inf=999999;
double mp[20][20];
int path[20][20];
int n,m;
3、 算法或程序模块
for(int i=0;i<m;i++){
cin>>Start>>End>>dis;
mp[Start][End]=dis;
}
for(int k=0;k<n;k++)//第k个点进行松弛
for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(mp[i][j]>mp[i][k]+mp[k][j])//如果能够缩短就更新距离 {mp[i][j]=mp[i][k]+mp[k][j];path[i][j]=k;//记录能松弛的点 }
三、 测试
1、 方案
假定根据城市道路抽象为如下图,起始地为V1顶点,目的地为V9顶点,对用弧上的距离和此时间段平均速度等信息如下表所示:
2、 结果
四、程序的源代码
#include<bits/stdc++.h>
using namespace std;
const int inf=999999;
double mp[20][20];
int path[20][20];
int n,m;
void print(int a,int b){if(path[a][b]==-1) return;//因为开始初始化为-1,这里就可以避免相邻的再次输出 print(a,path[a][b]);//前半部 cout<<path[a][b]<<"-->";//输出该点 print(path[a][b],b);//后半部
}int main(){// freopen("in.txt","r",stdin);while(1){printf("请选择1或2:\n"); printf("1.最短路程到达路线规划:\n");printf("2.最短时间到达路线规划:\n");int k;cin>>k;printf("选择完成:\n"); system("pause");if(k==1){system("cls");printf("请输入结点个数:\n");cin>>n;printf("请输入弧的个数:\n");cin>>m;memset(path,-1,sizeof(path));//初始化-1 for(int i=0;i<n;i++)for(int j=0;j<n;j++) if(i==j) mp[i][j]=0;else mp[i][j]=inf;int Start,End,dis;printf("请输入结点之间路径信息:\n");for(int i=0;i<m;i++){cin>>Start>>End>>dis;mp[Start][End]=dis;}for(int k=0;k<n;k++)//第k个点进行松弛for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(mp[i][j]>mp[i][k]+mp[k][j])//如果能够缩短就更新距离 {mp[i][j]=mp[i][k]+mp[k][j];path[i][j]=k;//记录能松弛的点 }//system("pause");printf("请输入起点和终点:\n");int aa,bb;cin>>aa>>bb;cout<<"The shortest path between vertices\n";if(mp[aa][bb]==inf){//两者不通 cout<<aa<<' '<<bb;cout<<" These two points cannot be reached\n\n"; }else{cout<<aa<<" to "<<bb<<" shortest path is "<<mp[aa][bb]<<" km"<<endl;cout<<"The specific path is\n";cout<<aa<<"-->";print(aa,bb);cout<<bb<<' ';cout<<endl<<endl;}printf("运行完成!\n");system("pause");system("cls");}else if(k==2){system("cls");printf("请输入结点个数:\n");cin>>n;printf("请输入弧的个数:\n");cin>>m;memset(path,-1,sizeof(path));//初始化-1 for(int i=0;i<n;i++)for(int j=0;j<n;j++) if(i==j) mp[i][j]=0;else mp[i][j]=inf;int Start,End;double dis,v;printf("请输入结点之间路径信息:\n");for(int i=0;i<m;i++){cin>>Start>>End>>dis>>v;mp[Start][End]=dis/v;}for(int k=0;k<n;k++)//第k个点进行松弛for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(mp[i][j]>mp[i][k]+mp[k][j])//如果能够缩短就更新距离 {mp[i][j]=mp[i][k]+mp[k][j];path[i][j]=k;//记录能松弛的点 }//system("pause");printf("请输入起点和终点:\n");int aa,bb;cin>>aa>>bb;cout<<"The shortest path between vertices\n";if(mp[aa][bb]==inf){//两者不通 cout<<aa<<' '<<bb;cout<<" These two points cannot be reached\n\n"; }else{cout<<aa<<" to "<<bb<<" shortest time is "<<mp[aa][bb]<<" hours"<<endl;cout<<"The specific path is\n";cout<<aa<<"-->";print(aa,bb);cout<<bb<<' ';cout<<endl<<endl;}printf("运行完成!\n");system("pause");system("cls");}else{printf("wrong choose!\n");}} return 0;
}