实验名称: 单源最短路径问题

实验地点:

实验目的:

1、  理解分支限界法的剪枝搜索策略;

2、  掌握分支限界法的算法柜架;

3、  掌握分支限界法的算法步骤;

4、  通过应用范例学习动态规划算法的设计技巧与策略;

实验原理

1. 基本思想

分支是使用广度优先策略,依次生成扩展结点的所有分支。

限界是在结点扩展过程中,计算结点的上界,搜索的同时剪掉某些分支。

分支限界法就是把问题的可行解展开,再由各个分支寻找最佳解。

与回溯法类似,分支限界法也是在解空间中搜索得到解;

不同的是,分支限界法会生成所有扩展结点,并舍弃不可能通向最优解的结点,然后根据广度优先/最小耗费优先,从活结点中选择一个作为扩展结点,使搜索向解空间上有最优解的分支推进。

2. 搜索策略

分支限界法首先生成当前扩展结点的所有分支,然后再从所有活结点中选择一个作为扩展结点。每一个活结点都要计算限界,根据限界情况判断是否剪枝,或选择最有利的结点。

实验内容:

1、使用分支限界法解决单源最短路径问题。

2、通过上机实验进行算法实现。

3、保存和打印出程序的运行结果,并结合程序进行分析,上交实验报告。

源程序:

方法一:

//单源最短路径class Graph{  //带权有向图
private:int n;          //顶点个数int **c;      //邻接矩阵int *dist;        //记录路径
public:void shortestPaths(int);Graph();         //根据情况构造图
};class MinHeapNode{        //最小堆的结点friend Graph;
private:int i;              //结点对应的顶点编号int length;          //结点记录的最短路径
public:int getI(){ return i; }void setI(int i){ this->i = i; }int getLength(){ return length; }void setLength(int length){ this->length = length; }
};class MinHeap{        //最小堆(虽然叫堆,但其实并不是用堆实现的)friend Graph;
private:int length;         //最小堆的长度,等同于顶点个数MinHeapNode *nodes;      //结点数组
public:MinHeap(int n){this->length = n;nodes = new MinHeapNode[n];}void deleteMin(MinHeapNode&);   //令当前节点出队列,并给出下一个扩展结点void insertNode(MinHeapNode N)      //结点入队列,将原结点的内容替换即可{nodes[N.getI()].setI(N.getI());nodes[N.getI()].setLength(N.getLength());}bool outOfBounds()      //检查队列为空{for(int i = 0;i < length;i++)if(nodes[i].getI() != -1)return false;return true;}
};void MinHeap::deleteMin(MinHeapNode &E)
{int j = E.getI();nodes[j].setI(-1);nodes[j].setLength(-1);        //标记为出队列int tmp = INT_MAX;for(int i = 0;i < length;i++){     //给出路径最短的结点作为扩展结点if(nodes[i].getI() != -1 && nodes[i].getLength() < tmp){E.setI(i);E.setLength(nodes[i].getLength());tmp = nodes[i].getLength();}}
}void Graph::shortestPaths(int start)
{MinHeap heap = MinHeap(n);    MinHeapNode E = MinHeapNode();     //别问,一开始还加了new,太久不写C++了E.i = start;    E.length = 0;dist[start] = 0; //初始为源点V,对应编号startwhile(true){for(int j = 0;j < n;j++){   //检查所有邻接顶点if(c[E.i][j] != 0){      //是否邻接if(E.length + c[E.i][j] < dist[j]){       //是否满足限界,当前路径小于记录的最短路径dist[j] = E.length + c[E.i][j];      //更新if(/*填入判断表达式*/){          //没有邻接顶点的点不入队,按情况调整,没有也可以,但会造成无效开销MinHeapNode N = MinHeapNode();    //创建一个新的结点,并令其入队列N.i = j;N.length = dist[j];heap.insertNode(N);}}}}if(heap.outOfBounds())  //队列为空,结束break;heap.deleteMin(E);    //该结点已经生成全部分支,出队列并取得下一扩展结点}
}

方法二:

#include <iostream>
#include<queue>
using namespace std;typedef struct ArcCell{int adj;//保存权值int info;//存储最短路径长度
}ArcCell,AdjMaxtrix[100][100];typedef struct{int data;int length;
}VerType;typedef struct{VerType vexs[100];//顶点向量AdjMaxtrix arcs;int vexnum;//顶点数int arcnum;//弧数
}Graph;Graph G;
queue<int> q;void CreateGraph()
{int m,n,t;printf("输入顶点数和弧数:");scanf("%d%d",&G.vexnum,&G.arcnum);printf("输入顶点:");for(int i=1;i<=G.vexnum;i++){scanf("%d",&G.vexs[i].data);G.vexs[i].length=10000;}for(int i=1;i<=G.vexnum;i++)for(int j=1;j<=G.vexnum;j++){G.arcs[i][j].adj=0;}printf("输入弧及权重:\n");for(int i=1;i<=G.arcnum;i++){scanf("%d%d%d",&m,&n,&t);G.arcs[m][n].adj=1;G.arcs[m][n].info=t;}}int NextAdj(int v,int w)
{for(int i=w+1;i<=G.vexnum;i++)if(G.arcs[v][i].adj)return i;return 0;//not found;
}void ShortestPaths(int v)
{int k=0;//从首个节点开始访问int t;G.vexs[v].length=0;q.push(G.vexs[v].data);while(!q.empty()){t=q.front();k=NextAdj(t,k);while(k!=0){if(G.vexs[t].length+G.arcs[t][k].info<=G.vexs[k].length)//减枝操作{G.vexs[k].length=G.vexs[t].length+G.arcs[t][k].info;q.push(G.vexs[k].data);}k=NextAdj(t,k);}q.pop();}
}void Print()
{for(int i=1;i<=G.vexnum;i++)printf("%d------%d\n",G.vexs[i].data,G.vexs[i].length);
}int main()
{CreateGraph();ShortestPaths(1);Print();return 0;
}

方法三:

#include <iostream>
#include<vector>
#include<queue>
using namespace std;typedef struct ArcCell{int u;//保存权值int info;//存储最短路径长度ArcCell(int a,int b):u(a),info(b){}
}ArcCell,AdjMaxtrix[100][100];typedef struct{int data;int length;
}VerType;typedef struct{VerType vexs[100];//顶点向量vector<ArcCell>arcs[1001];int vexnum;//顶点数int arcnum;//弧数
}Graph;Graph G;
queue<int> q;void CreateGraph()
{int m,n,t;printf("输入顶点数和弧数:");scanf("%d%d",&G.vexnum,&G.arcnum);printf("输入顶点:");for(int i=1;i<=G.vexnum;i++){scanf("%d",&G.vexs[i].data);G.vexs[i].length=10000;}printf("输入弧及权重:\n");for(int i=1;i<=G.arcnum;i++){scanf("%d%d%d",&m,&n,&t);G.arcs[m].push_back({n,t});}}void ShortestPaths(int v)
{int k=0;//从首个节点开始访问int t;G.vexs[v].length=0;q.push(G.vexs[v].data);while(!q.empty()){t=q.front();for(int i=0,j=G.arcs[t].size(); i<j; i++){k=G.arcs[t][i].u; printf("%d------%d\n",t,k);if(G.vexs[t].length+G.arcs[t][i].info<=G.vexs[k].length)//减枝操作{G.vexs[k].length=G.vexs[t].length+G.arcs[t][i].info;q.push(G.vexs[k].data);}}q.pop();}
}void Print()
{for(int i=1;i<=G.vexnum;i++)printf("%d------%d\n",G.vexs[i].data,G.vexs[i].length);
}int main()
{CreateGraph();ShortestPaths(1);Print();return 0;
}

实验结果:

心得与体会:

算法分析:

生成根节点的所有分支,全部入队列并记录路径;

在队列中选择路径最短的分支作为扩展结点

逐个生成分支,并判断分支的路径是否小于记录的最短路径;

若不小于,舍弃该分支;

若小于,该分支入队列;

生成所有分支后,回到2;

当队列为空时,算法结束。

体会:

1、  理解分支限界法的剪枝搜索策略;

2、  掌握分支限界法的算法柜架;

3、  掌握分支限界法的算法步骤;

4、  通过应用范例学习动态规划算法的设计技巧与策略;

5、  使用分支限界法解决单源最短路径问题。

参考文章

https://blog.csdn.net/weixin_44712386/article/details/105532881

https://blog.csdn.net/gzj_1101/article/details/48955177

https://www.jianshu.com/p/372dc2571784

C++——《算法分析与设计》实验报告——单源最短路径问题相关推荐

  1. c语言单源最短路径问题实验报告,单源最短路径问题Dijkstra算法的c语言实现

    求单源最短路径是图论中比较基本的问题,通常的Dijkstra算法是按阶段进行的,每个节点标有处理和未处理状态的标记,设立一个数组,每个数组中第i个元素为源节点到第i个节点的最短路径(当然,该数组的初值 ...

  2. 算法分析与设计实验报告 ——二分搜索程序算法的实现

    算法分析与设计实验报告 --二分搜索程序算法的实现 实验目的及要求 1.理解分治算法的概念和基本要素: 2.理解递归的概念: 3.掌握设计有效算法的分治策略: 4.通过二分搜索技术学习分治策略设计技巧 ...

  3. 算法分析与设计实验报告——实现汽车加油问题

    算法分析与设计实验报告--实现汽车加油问题 目录: 算法分析与设计实验报告--实现汽车加油问题 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与讨论 ...

  4. 算法分析与设计实验报告——二分搜索算法的实现

    算法分析与设计实验报告--二分搜索算法的实现 目录: 算法分析与设计实验报告--二分搜索算法的实现 一. 实验目的 二.实验要求 三. 实验原理 四. 实验过程(步骤) 五. 运行结果 六.实验分析与 ...

  5. 中北大学算法分析与设计实验报告一(BF算法)

    中北大学算法分析与设计实验报告一(BF算法) 1.实验名称 实验一 算法基础实验:数理基础与串匹配程序设计 2.实验目的 以字符串匹配问题为例,结合C等编程语言和链表.堆.栈等数据结构知识,基于BF算 ...

  6. 算法分析与设计实验报告

    计算机算法分析与设计实验报告 实验一:递归回溯 阶乘(Factorial) #include<iostream> using namespace std; int factorial(in ...

  7. 中北大学算法分析与设计实验报告六(最大团问题)

    中北大学算法分析与设计实验报告六(最大团问题) 1.实验名称 实验六 回溯与分支限界算法实验 2.实验目的 题目:最大团问题 强化学生利用回溯算法和优化处理实际问题的能力. 3.训练知识点集群 (1) ...

  8. C++——《算法分析》实验肆——单源最短路径问题

    实验目的: 1.理解分支限界法的剪枝搜索策略: 2. 掌握分支限界法的算法柜架: 3. 掌握分支限界法的算法步骤: 4. 通过应用范例学习动态规划算法的设计技巧与策略: 源程序: #include & ...

  9. 算法分析与设计实验报告三——动态规划算法

    一.实验目的 掌握动态规划方法贪心算法思想 掌握最优子结构原理 了解动态规划一般问题 二.实验内容 编写一个简单的程序,解决0-1背包问题.设N=5,C=10,w={2,2,6,5,4},v={6,3 ...

最新文章

  1. Configuration of OpenCV 2.4.7 in VS2012 (X86)
  2. PAT (Basic Level) 1058 选择题(模拟)
  3. 利用python爬虫(part7)--初识Xpath之Node节点
  4. 通用数据保护条例_欧盟《通用数据保护条例》——2019年的形势
  5. 阿里巴巴宣布架构调整;英伟达放大招!重磅发布 ​TensorRT 7 ,支持超千种计算变换;苹果、谷歌和亚马逊罕见结盟……...
  6. python爬虫淘宝评论图片_Python爬虫实战四之抓取淘宝MM照片
  7. 微前端子应用加载 vue-pdf 时跨域问题解决
  8. python spss modeler 比较_非常值得收藏的 IBM SPSS Modeler 算法简介
  9. 电影《后悔无期》的经典段子
  10. 计算机制图符号制作,基本流程图的制作-通过在线制图工具绘制
  11. Illumina的MiSeq™Dx系统在中国获得核准
  12. 安卓开发删除文件产生0KB文件
  13. 使用OBS双电脑直播(主副电脑)推流至哔哩哔哩
  14. Android OAID 深度探究
  15. 黑道圣徒3重制版如何设置中文
  16. PHP与MySQL外文文献译文和原文_PHP外文翻译文献-php网上书城系统外文翻译
  17. 如果你年满25岁还未到30岁
  18. 使用base64编码加密解密
  19. php程序+打印机,php程序如何调用打印机
  20. 使用mysql,建数据库建表操作

热门文章

  1. java宝典_JAVA宝典之_JAVA基础
  2. python typeerror console未定义,Python ctypes加载错误:未定义的符号
  3. flink 自定义 窗口_【Flink 精选】阐述 Watermark 机制,剖析 Watermark 的产生和传递流程...
  4. android纹理存储,android纹理文本
  5. asp ed什么意思 j_这部洗脑ED动画是如何创作出来的?
  6. java 跟踪错误程序_Java异常处理 如何跟踪异常的传播路径
  7. java的imshow方法_如何在循环中使用子图,imshow或图形来显示所有图像?
  8. java项目嗖嗖移动业务大厅项目报告_晋江市撰写节能评估报告的报告机构立项范本-文瑞...
  9. xamarin android pdf,Xamarin.Android - 下载pdf和视频到应用空间并打开
  10. 七十三、Python | Leetcode数字系列(上篇)