Java:使用 Fibonacci 堆实现 Dijkstra 算法

2023-12-14

新来的,但已经作为客人潜伏了一段时间了:)

好的,所以我一直在尝试使用 Fibonacci 堆(在 Java 中)执行 Dijkstra 的最短路径算法。经过一番搜索,我偶然发现了两个代表斐波那契堆的现成实现。第一个实现做得相当漂亮,可以找到here。第二种实现看起来不太优雅,是here.

现在,这一切看起来都很好。然而,我想将这些实现之一用于我的 Dijkstra 算法版本,但我还没有运气。使用中的Dijkstra的实现如下:

public void dijkstra(Vertex source) {
    {
        source.minDistance = 0.;
        PriorityQueue<Vertex> vertexQueue = new PriorityQueue<>();
        vertexQueue.add(source);

        while (!vertexQueue.isEmpty()) {
            Vertex u = vertexQueue.poll();

            // Visit each edge exiting u
            for (Edge e : u.adjacencies) {
                Vertex v = e.target;
                double weight = e.weight;
                double distanceThroughU = u.minDistance + weight;
                if (distanceThroughU < v.minDistance) {
                    vertexQueue.remove(v);
                    v.minDistance = distanceThroughU;
                    v.previous = u;
                    vertexQueue.add(v);
                }
            }
        }
    }
}

很明显,该实现使用基于 Java 的 PriorityQueue 类(我相信它基于二进制堆本身)。我希望修改上面的代码,以便它使用前面提到的 Fibonacci 堆实现而不是 Java 的 PriorityQueue。

我已经尝试了很多,但我就是不知道该怎么做,尽管我确信它就像替换几行代码一样简单。

我希望我说得足够清楚。这实际上是我在这些板上发表的第一篇文章。

任何帮助将不胜感激。

EDIT:为了回应评论,我想我应该用我的尝试场景之一来扩展我的帖子。

以下是上述 Dijkstra 方法的修改版本,使用前面链接的第二个 Fibonacci 堆实现:

public static void computePathsFibonacciHeap(Node source) {
    {
        source.minDistance = 0.;
        FibonacciHeap myHeap = new FibonacciHeap();
        myHeap.insert(source, source.minDistance);

        while (!myHeap.isEmpty()) {
            Node u = myHeap.min();

            // Visit each edge exiting u
            for (Edge e : u.adjacencies) {
                Node v = e.target;
                double weight = e.weight;
                double distanceThroughU = u.minDistance + weight;
                if (distanceThroughU < v.minDistance) {
                    v.minDistance = distanceThroughU;
                    myHeap.decreaseKey(v, v.minDistance);
                    v.previous = u;
                }
            }
        }
    }
}

这几乎是直接从伪代码转换而来的(因此完全有可能我没有正确翻译它)。我收到的错误是“decreaseKey() 得到了更大的值”。如果我尝试删除最小值,则会收到 NullPointerException。

我确信我做错了什么,我很想知道它是什么。再次,这是使用第二个 FHeap 实现。我更愿意使用第一个实现来完成它(它看起来更彻底/专业),但不幸的是我不知道如何做。


看来您缺少使用 Double.POSITIVE_INFINITY 添加堆中的所有节点(距离为 0.0 的源节点除外)。这就是为什么你会遇到 NullPointerExceptions,它们根本不在堆中。

我对几个开源斐波那契堆实现做了一些测试。您可以在这里找到测试本身:实验 dijkstra 算法。这也是我的 Dijkstra 算法的优先级队列版本:PriorityQueueDijkstra.java

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java:使用 Fibonacci 堆实现 Dijkstra 算法 的相关文章

随机推荐

  • 注释时间序列图

    我有一个日期索引数组 x 日期时间对象 和一个实际值数组 y 债券价格 执行以下操作 plot x y 生成一个完美的时间序列图 其中 x 轴标有日期 到目前为止没有问题 但我想在某些日期添加文本 例如 在2009年10月31日 我希望显示
  • 如何控制ConsumerGroup处理消息的并发度

    我正在使用 kafka node ConsumerGroup 来消费来自主题的消息 ConsumerGroup在消费消息时需要调用外部API 甚至可能需要一秒钟才能响应 我希望控制消费队列中的下一条消息 直到收到 API 的响应 以便按顺序
  • 尝试从 SAML 创建声明时出现错误“WIF10201:未找到有效的键映射”

    我正在尝试验证来自第三方 Siteminder IDP 的 SAML 响应 我已经安装了他们提供的证书 当我打电话给验证令牌方法 System IdentityModel Tokens 创建声明 我收到以下错误 WIF10201 找不到有效
  • Postgres 查询获取所有孩子的 id

    我是一个 SQL 菜鸟 到目前为止只编写了非常基本的查询 我有一张看起来像这样的桌子 item full name varchar 65535 item id bigint item owners varchar 255 item appr
  • git lock 错误背后的原因

    我正在一个拥有数百个分支的大型 git 存储库中工作 我在 Windows 上 通常当我git pull 它给了我多个锁定错误 例如 error cannot lock ref refs remotes origin branchname
  • 如何检测 UITableView beginUpdates/endUpdates 上的动画已结束?

    我正在使用插入 删除表格单元格insertRowsAtIndexPaths deleteRowsAtIndexPaths包装成beginUpdates endUpdates 我也在使用beginUpdates endUpdates调整 ro
  • 文件夹权限 - 部分或全部身份引用无法翻译

    我想在远程服务器上为域用户设置文件夹 ACL 但总是收到以下错误消息 部分或全部身份参考无法翻译 我究竟做错了什么 这是我的代码 string folderPath remoteServer testDirectory string acc
  • 两次时间之差(以分钟为单位)[关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我见过一些使用 Joda Time 和其他方法来计算两个日期之间以毫秒为单位的差异的示例 但是如何将这些应用到仅以分钟为单位计算两个时间之间的差异呢 例如 下午 2 45 和上午 1
  • PHP 致命错误:调用未定义的函数?

    因此 当我将网站托管在我的网络主机上时 我的网站出现了问题 我收到这个错误 PHP Fatal error Call to undefined function getSkillIcons 奇怪的是 在本地 Xampp 它工作得很好 这就是
  • Qt:如何获取正在运行的 QProcess 的实时输出

    我必须在 QProcess 运行时获取它的输出 因此我编写了以下代码 CommandExecutor C CommandExecutor C mProcessStatus AI UNKNOWN mOnTdiActiveCallback mT
  • 使用 Embed API 嵌入 Google Analytics 位置地图视图

    下面是 Google 分析网站上的视图屏幕截图 地理位置 gt 位置 gt 主要维度 城市 我想嵌入这个确切的视图 或者使用 google 的 Embed API 尽可能类似地复制它 并将其显示在我自己的网站上 我已经按照这里的教程进行操作
  • 为什么要使用指针(性能)?

    我想知道是否有关于原始对象与对象指针的性能基准 我知道在引用类型 例如地图 上使用指针是没有意义的 所以请不要提及它 我知道如果数据需要更新 您 必须 使用指针 所以请不要提及它 我发现的大多数答案 文档基本上都改写了官方文档中的指南 If
  • 类装饰器Nestjs修改类中的每个方法

    我想创建一个装饰器 它可以获取类的所有方法并用某些功能包装它们 对于这个例子 只需像这样记录 export function CustDec
  • MuleStudio studio:工作室目标未能执行

    我在 Mule Studio 工作区 从 Mule Studio 中 复制 粘贴了一个工作项目来创建一个新项目 之后 我可以在新项目上进行 mvn clean 安装 一切正常 然后 在对 pom 进行任何修改 即添加空行 后 我收到以下错误
  • 是否可以将数据绑定到枚举并显示用户友好的值? [复制]

    这个问题在这里已经有答案了 我想显示我的合同的状态 两者声明如下 public enum RentStatus Description Preparation description Preparation Description Acti
  • 当用户滚动到页面部分时触发 CSS 动画

    我的网站上有一个简单的 CSS 动画 我想在其中显示 5 个 div 一次连续显示一个 一切正常 但我想在用户滚动到我网站上的特定部分时触发该动画 现在动画在页面加载时开始 这是我的代码 div div div img src https
  • AngularDart:如何将事件从子组件传递到二级父组件

    我将 StreamController 与事件一起使用 本质上我有一个 3 级组件层次结构 我们称它们为 A B C 层次结构是A gt B gt C 事件的起源在c中 我希望事件由A处理 我知道使用 Output 的直接父 gt 子关系很
  • 如何在没有 Activity 的情况下使用 LocalBroadcastManager

    我有我的课 ABC 通过扩展BroadcastReceiver 但最近我偶然发现LocalBroadcastManager 这是我的班级声明 public class ABC extends BroadcastReceiver 因此 ABC
  • CSVReader - 使用“作为转义字符时出现错误

    我正在使用 OpenCSV 我有一个CSVReader尝试解析 CSV 文件 该文件有引号字符 和分隔符 和转义字符也 请注意 CSV 包含以下单元格 ballet 24 classes 实际上代表这些值 ballet 24 classes
  • Java:使用 Fibonacci 堆实现 Dijkstra 算法

    新来的 但已经作为客人潜伏了一段时间了 好的 所以我一直在尝试使用 Fibonacci 堆 在 Java 中 执行 Dijkstra 的最短路径算法 经过一番搜索 我偶然发现了两个代表斐波那契堆的现成实现 第一个实现做得相当漂亮 可以找到h