专业英语
选论文
Universal Optimality of Dijkstra via Beyond-Worst-Case Heaps
(通过超越最坏情况堆实现 Dijkstra 的普遍最优性)
[Submitted on 20 Nov 2023 (v1), last revised 28 Oct 2024 (this version, v3)]
[2023年11月20日提交(v1),最后修订于2024年10月28日(本版本,v3)]
发表在FOCS顶会上
https://arxiv.org/abs/2311.11793 (论文链接)
https://arxiv.org/pdf/2311.11793 (pdf链接)
https://online.updf.com/pdf/share?shareId=866495207397400577 (_zh-CN.pdf,pdf中文翻译版)
演讲稿
- 前言
- 介绍作者
- 透过作者才能深入剖析他的学术思想
- 介绍发表的会议
- 强调论文的价值
- 研究背景
- 强调该研究的重要性及其带来的价值
- 研究意义
- 问题概念定义和问题由来
- 创新点/贡献
- 说明本文的创新点以及对领域的贡献
- 介绍作者
- 内容
- 目的
- 描述研究的总体目标和需要解决的问题
- 方法
- 概述研究中使用的主要方法和技术
- 结果
- 总结研究得出的主要结果和发现
- 结论
- 提出研究的结论和其对实际应用的潜在贡献
- 目的
PPT
暂无
代码实现
朴素 dijkstra 算法,复杂度 \(O(n^2)\)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll inf = 0x3f3f3f3f3f3f3f3f;
class edge {
public:
int v;
ll w;
edge() {}
edge(int v, ll w) : v(v), w(w) {}
};
class graph {
public:
int n;
vector<vector<edge>> adj;
graph() {}
graph(int n) { init(n); }
void init(int n) {
this -> n = n;
adj.resize(n + 1, {});
}
void addEdge(int u, int v, ll w) {
adj[u].emplace_back(edge(v, w));
adj[v].emplace_back(edge(u, w));
}
ll dijkstra(int start, int terminus = -1) {
vector<ll> distance(n + 1, inf);
vector<bool> visit(n + 1);
distance[start] = 0;
for (int i = 1; i <= n; ++ i) {
ll u = 0, MinimumDistance = inf;
for (int j = 1; j <= n; ++ j) {
if (!visit[j] && distance[j] < MinimumDistance) {
u = j;
MinimumDistance = distance[j];
}
}
for (auto Edge : adj[u]) {
if (distance[Edge.v] > distance[u] + Edge.w) {
distance[Edge.v] = distance[u] + Edge.w;
}
}
}
ll res = inf;
if (terminus == -1) {
for (int i = 1; i <= n; ++ i) {
if (i != terminus) {
res = min(res, distance[i]);
}
}
} else {
res = distance[terminus];
}
return res;
}
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
graph a(n);
int start, terminus;
cin >> start >> terminus;
for (int i = 1; i <= m; ++ i) {
int u, v;
cin >> u >> v;
g.addEdge(u, v);
}
ll ans = g.dijkstra(start, terminus);
cout << ans << "\n";
}
二叉堆(Binary Heaps) 实现的优化版本,复杂度 \(O(mlog(m))\)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll inf = 0x3f3f3f3f3f3f3f3f;
class edge {
public:
ll v, w;
edge() {}
edge(int v, ll w) : v(v), w(w) {}
};
class node {
public:
ll dis, u;
bool operator>(const node& a) const { return dis > a.dis; }
};
class graph {
public:
int n;
vector<vector<edge>> adj;
graph() {}
graph(int n) { init(n); }
void init(int n) {
this -> n = n;
adj.resize(n + 1, {});
}
void addEdge(int u, int v, ll w = 1) {
adj[u].emplace_back(edge(v, w));
adj[v].emplace_back(edge(u, w));
}
ll dijkstra(int start, int terminus = -1) {
vector<ll> distance(n + 1, inf);
vector<bool> visit(n + 1);
priority_queue<node, vector<node>, greater<node>> q;
distance[start] = 0;
q.push({0, start});
while (!q.empty()) {
int u = q.top().u; q.pop();
if (visit[u]) continue;
visit[u] = 1;
for (auto Edge : adj[u]) {
if (distance[Edge.v] > distance[u] + Edge.w) {
distance[Edge.v] = distance[u] + Edge.w;
q.push({distance[Edge.v], Edge.v});
}
}
}
ll res = inf;
if (terminus == -1) {
for (int i = 1; i <= n; ++ i) {
res = min(res, distance[i]);
}
} else {
res = distance[terminus];
}
return res;
}
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
cout.tie(nullptr)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
graph g(n);
int start, terminus;
cin >> start >> terminus;
for (int i = 1; i <= m; ++ i) {
int u, v;
cin >> u >> v;
g.addEdge(u, v);
}
ll ans = g.dijkstra(start, terminus);
cout << ans << "\n";
}
论文证明了:用任何具有工作集属性的Fibonacci类优先队列实现的Dijkstra算法在比较加法模型下是距离排序问题的普遍最优算法
事实上论文研究的Dijkstra算法与上面写的 二叉堆实现的优先队列 的主体函数的代码一般无二
唯一的区别就是优先队列的实现不同,因为传统优先队列的实现是二叉堆,而非Fibonacci堆
Fibonacci类优先队列能将原本 全为 O(log(n)) 复杂度的 GetMin, Insert, DecreaseKey 操作都优化至 O(1)
而 ExtractMin 复杂度保持不变仍旧为 O(log(n))
class FibonacciHeap {
};
词汇
单源最短路 Single source shortest circuit

浙公网安备 33010602011771号