专业英语

选论文

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

论文内容

posted @ 2024-11-23 00:51  Proaes  阅读(65)  评论(0)    收藏  举报