【算法学习】分枝限界法(二)

简介: 【算法学习】分枝限界法

03

priority queue实现


接下来是优先队列式分枝限界法,我们以单源最短路径问题为例。

最短路径依旧是一个熟悉的问题,可以通过过去的推文了解就不多解释了

【算法学习】最短路径问题

 

先简单介绍一下优先队列:

优先队列可以分为最大、最小优先队列。相比于先进先出的普通队列,优先队列每次都是最大(或最小)的元素优先出队

 

在单源最短路径问题中,我们采用的剪枝函数则类似于之前提到的Dijkstra算法(其实它本身也就是源于BFS),通过寻找当前离原点最近的点进行下一步操作;通过松弛操作得出下一层子节点。说是最优优先出队,其实这里也只有最小点一个出队拓展新子点了。之前推文里有提到具体算法,可以参考一下,就不难理解了。

 

这里暂时不深入讲解如何实现优先队列,而是直接通过头文件调用。由于我也不是很习惯用优先队列,这里参考了网上的代码。具体讲解参见注释:

 

Code:


//优先队列式分支限界法 解单源最短路径问题
//来源互联网 ,作者csdn zzzsdust 原文链接见后文 
#include <bits/stdc++.h>  //头文件中附带有优先队列 
using namespace std;
class MinHeapNode  //最小堆 
{
public:
    int id;
    int length; //从起始点 v 到点 id 的距离
public:
    friend bool operator < (const MinHeapNode &a, const MinHeapNode &b)   //运算符重载 
    {
        return a.length < b.length;
    }
    friend bool operator > (const MinHeapNode &a, const MinHeapNode &b)
    {
        return a.length > b.length;
    }
};
const int max_ = 0x3f3f3f;
int Graph[100][100];  //输入两点间距离 
int dist[100];    //到原点距离 
int pre[100];   //记录最短路径中的前一个点 
int n, m, v;
void OutPutPath(int i)   //输出到原点的最短路径 
{
    if(i == pre[i])
    {
        printf("%d", i);
        return;
    }
    else
    {
        OutPutPath(pre[i]);
        printf(" %d", i);
    }
}
void OutPut()
{
    for(int i = 1; i <= n; ++i)
    {
        if(i != v)
        {
            printf("点 %d 到 %d 的最短距离是 %d\n", v, i, dist[i]);
            printf("路径为:");
            OutPutPath(i);
            printf("\n");
        }
    }
}
//划重点!! 
void ShortestPaths()
{
    priority_queue<MinHeapNode, vector<MinHeapNode>, greater<MinHeapNode> > q;   
  /*调用优先队列 ,
  第一个参数是数值类型;
  第二个参数是存放数值的容器类型,一般用vector;
  第三个参数为排序规则。 
  greater升序,即小的先出;less降序,即大的先出。
    具体函数: 
     1.插入         .push()函数
     2.取出顶端元素   .top()函数
     3.删除顶端元素   .pop()函数
     4.大小         .size()函数
     5.是否为空      .empty()函数
    */
    memset(dist, max_, sizeof(dist)); //初始化距离 
    dist[v] = 0; 
    pre[v] = v;
    MinHeapNode cur_p;
    cur_p.id = v;
    cur_p.length = 0;
    q.push(cur_p);
    while(true)
    {
        if(q.empty() == 1) //全员松弛完毕 
            break;
        cur_p = q.top(); //取出堆顶的点(距离最短) 
        q.pop(); // 在优先队列中删除刚取出的点
        for(int i = 1; i <= n; ++i)
        {
            if(Graph[cur_p.id][i] != max_ && (cur_p.length + Graph[cur_p.id][i] < dist[i]))  //剪枝函数,也就是Dijkstra中的松弛 
            {
                dist[i] = cur_p.length + Graph[cur_p.id][i];
                pre[i] = cur_p.id;
                MinHeapNode temp;
                temp.id = i;
                temp.length = dist[i];
                q.push(temp);
            }
        }
    }  
}
void InPut()   //输入数据 
{
    int x, y, len;
    scanf("%d %d %d", &v, &n, &m);  //以v为原点,n个点,m条边。 
    memset(Graph, max_, sizeof(Graph));   //默认设置为最大,表示无法到达 
    for(int i = 1; i <= m; ++i)
    {
        scanf("%d %d %d", &x, &y, &len);
        Graph[x][y] = Graph[y][x] = len; //无向图!! 
    }
}
int main()
{
    InPut();
    ShortestPaths();
    OutPut();
}




微信图片_20220422151431.jpg


Reference


https://blog.csdn.net/qjt19950610/article/details/89476784 


https://blog.csdn.net/m0_38015368/article/details/80449014


Introduction to The Design and Analysis of Algorithms

by Anany Levitin     潘彦 译


后记:


分枝限界法最有名的作用还是求解整数规划问题。


这部分问题我们暂且搁一会儿,等未来再讲。

(关键看我什么时候编出正确的代码)


其实到这里,一个部分的内容也结束了。


这一部分主要是讲算法设计思想。


然而rookie的我连数据结构的不过关。。。


因此打算接下来一段时间恶补一波。


可能会写相关的内容。敬请期待~~

相关文章
|
23天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
19天前
|
机器学习/深度学习 人工智能 自然语言处理
【EMNLP2024】基于多轮课程学习的大语言模型蒸馏算法 TAPIR
阿里云人工智能平台 PAI 与复旦大学王鹏教授团队合作,在自然语言处理顶级会议 EMNLP 2024 上发表论文《Distilling Instruction-following Abilities of Large Language Models with Task-aware Curriculum Planning》。
|
23天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
23天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
23天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
23天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
23天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
23天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
23天前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构的基本概念;算法的基本概念、特性以及时间复杂度、空间复杂度等举例说明;【含常见的报错问题及其对应的解决方法】
|
23天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!