如何找到循环图中两个节点之间的最长路径?

2023-11-22

我已经解决了大部分发布的问题here,除了最长的路径之外的所有路径。我读过关于最长路径的维基百科文章,如果图是非循环的,这似乎很容易出现问题,而我的不是。

那我该如何解决这个问题呢?通过检查所有可能的路径进行暴力破解?我该如何开始这样做呢?

我知道大约 18000 的图表会花费很多时间。但无论如何我只是想开发它,因为项目需要它,我只会测试它并在较小比例的图表上向讲师展示它,其中执行时间仅为一两秒。

至少我完成了所需的所有任务,并且我有一个正在运行的概念证明,它可以工作,但在循环图上没有更好的方法。但我不知道从哪里开始检查所有这些路径......


解决办法就是暴力破解。你可以做一些优化来加速它,有些是微不足道的,有些是非常复杂的。我怀疑你能否让它在台式计算机上以足够快的速度运行 18,000 个节点,即使可以,我也不知道如何实现。然而,暴力破解的工作原理如下。

Note:如果您对确切的答案感兴趣,Dijkstra 和任何其他最短路径算法都不适用于此问题。

Start at a root node *root*
Let D[i] = longest path from node *root* to node i. D[*root*] = 0, and the others are also 0.

void getLongestPath(node, currSum)
{
    if node is visited
        return;
    mark node as visited;

    if D[node] < currSum
        D[node] = currSum;

    for each child i of node do
        getLongestPath(i, currSum + EdgeWeight(i, node));

    mark node as not visited;
}

让我们在这张图上手动运行一下:1 - 2 (4), 1 - 3 (100), 2 - 3 (5), 3 - 5 (200), 3 - 4 (7), 4 - 5 (1000)

Let the root be 1. We call getLongestPath(1, 0);
2 is marked as visited and getLongestPath(2, 4); is called
D[2] = 0 < currSum = 4 so D[2] = 4.
3 is marked as visited and getLongestPath(3, 4 + 5); is called
D[3] = 0 < currSum = 9 so D[3] = 9.
4 is marked as visited and getLongestPath(4, 9 + 7); is called
D[4] = 0 < currSum = 16 so D[4] = 16.
5 is marked as visited and getLongestPath(5, 16 + 1000); is called
D[5] = 0 < currSum = 1016 so D[5] = 1016.
getLongestPath(3, 1016 + 200); is called, but node 3 is marked as visited, so nothing happens.
Node 5 has no more child nodes, so the function marks 5 as not visited and backtracks to 4. The backtracking will happen until node 1 is hit, which will end up setting D[3] = 100 and updating more nodes.

这是迭代的样子(未经测试,只是一个基本想法):

Let st be a stack, the rest remains unchanged;
void getLongestPath(root)
{
    st.push(pair(root, 0));

    while st is not empty
    {
        topStack = st.top();
        if topStack.node is visited
            goto end;
        mark topStack.node as visited;

        if D[topStack.node] < topStack.sum
            D[topStack.node = topStack.sum;

        if topStack.node has a remaining child (*)
            st.push(pair(nextchild of topStack.node, topStack.sum + edge cost of topStack.node - nextchild)) 

        end:
        mark topStack.node as not visited
        st.pop();
    }
}

(*) - 这是一个有点问题 - 你必须为每个节点保留一个指向下一个子节点的指针,因为它可以在 while 循环的不同迭代之间改变,甚至重置自身(当你弹出该节点时,指针会重置自己)topStack.node节点离开堆栈,因此请务必重置它)。这是在链接列表上最容易实现的,但是您应该使用int[]列出或vector<int>列表,以便能够存储指针并进行随机访问,因为您将需要它。你可以保留例如next[i] = next child of node i in its adjacency list并相应更新。您可能会遇到一些边缘情况,并且可能需要不同的end:情况:正常的一种情况和当您访问已经访问过的节点时发生的一种情况,在这种情况下不需要重置指针。也许在您决定将某些内容推入堆栈之前移动已访问的条件以避免这种情况。

明白为什么我说你不应该打扰吗? :)

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

如何找到循环图中两个节点之间的最长路径? 的相关文章

随机推荐

  • 读取 JPG 文件的 XMP 元数据

    我正在开发 Android 应用程序 该应用程序应该利用 Google 相机的新深度图生成功能 基本上谷歌已经描述了所使用的元数据here 我可以访问大部分元数据 但不幸的是 最重要的数据被编码为extendXmp 并且我无法获得任何XMP
  • sql server 将日期转换为字符串 MM/DD/YYYY

    我正在使用 SQL Server 2008 我有以下内容 select convert varchar 20 fmdate from Sery 如何将日期转换为字符串 使其显示为 MM DD YYYY 该任务应该由软件堆栈中的下一层来完成
  • 如何在 C++ 中编码大型复杂的常量数据结构

    过去 我使用过 gccC99 样式复合文字扩展到 C 来编码代码中的嵌套常量数据结构 这是一个例子 include
  • 获取文档中的所有链接

    给定 Google Docs Drive 中的 普通文档 例如段落 列表 表格 其中包含分散在整个内容中的外部链接 如何使用 Google Apps 脚本编译存在的链接列表 具体来说 我想通过搜索来更新文档中所有损坏的链接oldText在每
  • Instagram Instagram 标题不起作用

    我有以下用于在 Instagram 上分享文章的代码 void shareInstagram NSURL instagramURL NSURL URLWithString instagram app if UIApplication sha
  • 如何将外部 DOM 附加到 React 组件?

    我有一个页面 其中包含在服务器中呈现的表单 它处理验证以及选择的正确值 我想隐藏该表单的 DOM 并将其附加到 React 组件中 以便我可以在 React router 中使用它 const NewItem React createCla
  • UICollectionView 滚动很慢

    我刚刚创建了一个UICollectionView其中用户可以将手机中的图像添加到应用程序的相册功能中 我将图像保存到文档目录中的子目录中 以便可以添加和删除更多图像 但是 当我上下滚动集合视图时 它非常滞后 怎样才能让滚动条又漂亮又流畅呢
  • “点击恢复”暂停文本 SpriteKit

    我知道 SpriteKit 已经处理了当应用程序进入非活动状态时暂停游戏的问题 但我想做的是在应用程序重新进入活动状态时添加一个 SKLabelNode 点击恢复 现在它正在正确调用我的函数并暂停游戏 但文本没有显示 AppDelegate
  • 具有多个自变量的 Python curve_fit

    蟒蛇的curve fit计算具有单个自变量的函数的最佳拟合参数 但是有没有办法使用curve fit或者其他什么 以适应具有多个自变量的函数 例如 def func x y a b c return log a b log x c log
  • 如何检测实体 EntityState 的更改?

    我想在客户列表的每一行上放置一个 删除 按钮和一个 取消 按钮 当客户 未更改 时 取消 按钮将被禁用 但是 当客户转换到更改状态 已添加 已修改 已删除 时 我想启用 取消 按钮 以便用户可以在保存之前撤消更改 无论它们是什么 我几乎可以
  • 如何防止 PHP DOMDocument“修复”您的 HTML 字符串

    我一直在尝试使用 HTML DOM 对象来解析网页 以便将它们用于应用程序来扫描它们的 SEO 质量 但是我遇到了一些问题 出于测试目的 我编写了一个小型 HTML 页面 其中包含以下不正确的 HTML 正如您所看到的 标题位于 head
  • EF Core 多个导航属性产生循环依赖

    我有以下映射配置 入门级 entity HasOne e gt e CurrentHandling WithOne HasForeignKey
  • Django 多处理和数据库连接

    背景 我正在开发一个使用 Django 和 Postgres 数据库的项目 我们还使用 mod wsgi 以防万一 因为我的一些网络搜索提到了它 在提交 Web 表单时 Django 视图启动一项需要花费大量时间 超过用户想要等待的时间 的
  • 当我们创建空的不可变列表/集合/映射时,是否有任何实际应用/用例

    Java 9 提供了一种创建空不可变列表 集合和映射的方法 List list List of Set set Set of Map map Map of 但我无法理解创建空的不可变列表 集合 映射的实际用例是什么 请帮助我理解空的不可变列
  • 如何在 Zend Framework 2 中引导会话

    在 Zend Framework 2 中启动和运行会话的最佳方法是什么 我尝试过设置session start 在我的 index php 文件中 但随后在引导任何自动加载器之前运行该文件 导致我的会话中存在不完整的对象 在 ZF1 中 您
  • C# - 如何打印宽高比/整页

    我正在单击按钮时打印图表控件 chart1 SaveImage ms ChartImageFormat Bmp Bitmap bm new Bitmap ms PrintDocument doc new PrintDocument doc
  • 如何覆盖 setup.py 默认使用的编译器 (GCC) 标志?

    我明白那个setup py使用相同的CFLAGS用于构建 Python 我有一个我们的 C 扩展存在段错误 我需要构建它without O2因为 O2正在优化一些值和代码 以便核心文件不足以确定问题 我只需要修改setup py以便 O2未
  • 如何从 Java 中的 URL 读取图像?

    我的 Web 应用程序中有提供图像的 servlet 当我使用浏览器图像访问这些 url 时 服务器是正确的 然后我有另一个调整图像大小的 servlet 想法是通过调整大小 servlet 中的 url 访问获取图像 然后调整图像大小 但
  • 最佳实践 - 使用 Symfony 2 删除链接

    在 Symfony 2 中 创建删除记录的链接的最佳方法是什么 我可以定义一条路线 entity delete只接受一个DELETE方法 但我不知道如何创建DELETE来自模板的链接 创建也是同样的道理PUT links 所以你会怎么做 接
  • 如何找到循环图中两个节点之间的最长路径?

    我已经解决了大部分发布的问题here 除了最长的路径之外的所有路径 我读过关于最长路径的维基百科文章 如果图是非循环的 这似乎很容易出现问题 而我的不是 那我该如何解决这个问题呢 通过检查所有可能的路径进行暴力破解 我该如何开始这样做呢 我