贪心算法实验(求解最短路径)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计实验报告第五次实验
输入较小的有向带权图结果:
测试结果
输入较大的有向带权图结果:
实验分析在实验中输入了两个有向带权图,一组是结点较少,贪心判断会少一点,另一组的结点稍微多一点,贪心判断会多一些,通过上面的图和下面的结果的比较,我们可以发现结果是正确的,说明程序设计没有问题。观察两个图所用的时间的多少,我们发现这两个结点所用的时间是相对接近的,并没有很大的差距。不过这一个程序有一个问题就是每一次都需要我们手动的去输入一个图的邻接矩阵,对于结点很多的图显然是不合适,所以我们可以通过读文件来减少工作量,下次要改进。
附录:
完整代码(贪心法)
//贪心算法 Dijkstra求单源最短路径
#include
#include
#include
#include
using namespace std;
const int N=10;
const int M=1000; //定义无限大的值
template
void Dijkstra(int n,int v,Type dist[],int prev[],Type c[][N+1]);
//输出最短路径,源点v,终点i,prev[]保存父结点
void Traceback(int v,int i,int prev[]);
//参数分别为顶点个数n,源结点v,源结点到其他结点的距离数组dist[],父结点数组prev[],各结点之间的距离数组c[][N+1]
template
void Dijkstra(int n,int v,Type dist[],int prev[],Type c[][N+1])
{ bool s[N+1]; //s数组表示各结点是否已经遍历
for(int i=1;i<=n;i++)
{
dist[i]=c[v][i]; //dist[i]表示当前从源到顶点的最短路径长度
s[i]=false;
if(dist[i]==M)
prev[i]=0; //记录从源到顶点i的最短路径的前一个顶点else
prev[i]=v;
}
dist[v]=0;
s[v]=true;
for(int i=1;i { int temp=M; int u=v; //上一个顶点 //取出v-s中具有最短路径长度的顶点u for(int j=1;j<=n;j++) { if((!s[j])&&(dist[j] { u=j; temp=dist[j]; //更新最小值temp } } s[u]=true; //根据做出的贪心选择更新dist的值 for(int j=1;j<=n;j++) //当¡加入S集合后,更新dist[]的值 { if((!s[j])&&(c[u][j] { Type newdist=dist[u]+c[u][j]; if(newdist { dist[j]=newdist; prev[j]=u; } } } } } //输出最短路径,v源点,i终点,prev[]为父结点数组 void Traceback(int v,int i,int prev[]) { if(v==i) { cout< return; } Traceback(v,prev[i],prev); //回溯输出最短路径 cout<<"->"< } int main() { int i,j; int v=1; //源点为1 int dist[N+1],prev[N+1],c[N+1][N+1]; cout<<"有向图权的矩阵为:"< for(i=1;i<=N;i++) //输入邻接矩阵 { for(j=1;j<=N;j++) cin>>c[i][j]; } clock_t start,end,over; //计算程序运行时间的算法 start=clock(); end=clock(); over=end-start; start=clock(); Dijkstra(N,v,dist,prev,c); //调用dijkstra算法函数 for(i=2;i<=N;i++) { cout<<"源点1到点"< Traceback(1,i,prev); //输出最短路径 cout< } end=clock(); printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间 system("pause"); return 0; }